﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;

namespace Test4AngeloRTV_Video
{
    public partial class Form1 : Form
    {
        public const int BI_RGB = 0;
        public const int DIB_RGB_COLORS = 0;

        private IntPtr Mythread;
        private int Max_PORT = 4;
        private int ISR_ON;
        private IntPtr[] Event_Angelo = new IntPtr[4];
        private long Int_Count;
        private int Cur_Video_Format = 3;
        private int Cur_Width =384;
        private int Cur_Height =288;
        private int iwidth =384;
        private int iheight =288;
        private BITMAPINFO bmpinfo = new BITMAPINFO();
        private Int16 Byte_Pixel = 3;
        private IntPtr ghdc;
        private IntPtr hbitbap;
        private IntPtr Temp0;

        IntPtr panelDC;

        public delegate void lpCallBack(IntPtr videoBufferAddress, int portNo);
        [DllImport("AngeloRTV.dll")]
        public static extern int AngeloRTV_Initial(int nIndex);
        [DllImport("AngeloRTV.dll")]
        public static extern int AngeloRTV_Close(int nIndex);
        [DllImport("AngeloRTV.dll")]
        public static extern int AngeloRTV_Capture_Stop(int PortNo);
        [DllImport("AngeloRTV.dll")]
        public static extern int AngeloRTV_Set_Callback(int PortNo, lpCallBack callBack);
        [DllImport("AngeloRTV.dll")]
        public static extern int AngeloRTV_Set_Color_Format(int PortNo, byte ColorFormat);
        [DllImport("AngeloRTV.dll")]
        public static extern int AngeloRTV_Set_Video_Format(int PortNo, byte Value);
        [DllImport("AngeloRTV.dll")]
        public static extern int AngeloRTV_Set_Image_Config(int PortNo, byte ConfigIndex, byte Value);
        [DllImport("AngeloRTV.dll")]
        public static extern int AngeloRTV_Select_Channel(int PortNo, int Multiplex);
        [DllImport("AngeloRTV.dll")]
        public static extern int AngeloRTV_Set_Int_Event(int PortNo, IntPtr hEvent);
        [DllImport("AngeloRTV.dll")]
        public static extern int AngeloRTV_Capture_Start(int PortNo, long CaptureNo);
        [DllImport("AngeloRTV.dll")]
        public static extern int AngeloRTV_Sync_Grab(int PortNo, long Start_Address, long Width, long Height, long Size_byte);

        [DllImport("user32.dll")]
        static extern IntPtr GetDC(IntPtr hWnd);
        [DllImport("kernel32.dll")]
        static extern bool SetEvent(IntPtr hEvent);
        [DllImport("kernel32.dll")]
        static extern bool TerminateThread(IntPtr hThread, uint dwExitCode);
        [DllImport("gdi32.dll")]
        static extern IntPtr CreateDIBSection(IntPtr hdc, [In] ref BITMAPINFO pbmi,
           uint iUsage, out IntPtr ppvBits, IntPtr hSection, uint dwOffset);
        [DllImport("gdi32.dll", SetLastError = true)]
        static extern IntPtr CreateCompatibleDC(IntPtr hdc);
        [DllImport("gdi32.dll", ExactSpelling = true, PreserveSig = true, SetLastError = true)]
        static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
        [DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory")]
        static extern void CopyMemory(IntPtr Destination, IntPtr Source, uint Length);
        [DllImport("gdi32.dll")]
        static extern bool BitBlt(IntPtr hdc, int nXDest, int nYDest, int nWidth,
           int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, uint dwRop);
        [DllImport("gdi32.dll")]
        static extern int GetDIBits(IntPtr hdc, IntPtr hbmp, uint uStartScan,
           uint cScanLines, [Out] byte[] lpvBits, ref BITMAPINFO lpbmi, uint uUsage);

        [StructLayout(LayoutKind.Sequential)]
        public class BITMAPINFOHEADER
        {
            public Int32 biSize;
            public Int32 biWidth;
            public Int32 biHeight;
            public Int16 biPlanes;
            public Int16 biBitCount;
            public Int32 biCompression;
            public Int32 biSizeImage;
            public Int32 biXPelsPerMeter;
            public Int32 biYPelsPerMeter;
            public Int32 biClrUsed;
            public Int32 biClrImportant;
        }
        [StructLayout(LayoutKind.Sequential)]
        public class RGBQUAD
        {
            public Byte rgbBlue;
            public Byte rgbGreen;
            public Byte rgbRed;
            public Byte rgbReserved;
        }
        [StructLayout(LayoutKind.Sequential)]
        public class BITMAPINFO
        {
            public BITMAPINFOHEADER bmiHeader = new BITMAPINFOHEADER();
            public RGBQUAD bmiColors = new RGBQUAD();
        }
        public enum TernaryRasterOperations : uint
        {
            SRCCOPY = 0x00CC0020,
            SRCPAINT = 0x00EE0086,
            SRCAND = 0x008800C6,
            SRCINVERT = 0x00660046,
            SRCERASE = 0x00440328,
            NOTSRCCOPY = 0x00330008,
            NOTSRCERASE = 0x001100A6,
            MERGECOPY = 0x00C000CA,
            MERGEPAINT = 0x00BB0226,
            PATCOPY = 0x00F00021,
            PATPAINT = 0x00FB0A09,
            PATINVERT = 0x005A0049,
            DSTINVERT = 0x00550009,
            BLACKNESS = 0x00000042,
            WHITENESS = 0x00FF0062
        }

        public Form1()
        {
            InitializeComponent();
        }

        private void InitialCard()
        {
            int result;
            for (int i = 0; i < Max_PORT; i++)
                result = AngeloRTV_Initial(i);
        }

        private void CloseCard()
        {
            int result;
            for (int i = 0; i < Max_PORT; i++)
                result = AngeloRTV_Close(i);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            panelDC = GetDC(panel1.Handle);
            InitialCard();

        }

        private void MyCallback(IntPtr VideoBufferAddress, int PortNo)
        {
            Int_Count += 1;
            CopyMemory(Temp0, VideoBufferAddress, (uint)(iwidth * iheight * Byte_Pixel));
            BitBlt(panelDC, 0, 0, iwidth, iheight, ghdc, 0, 0, (uint)TernaryRasterOperations.SRCCOPY);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            int Event;
            int ThreadId;
            int Port;

            AngeloRTV_Capture_Stop(0);
            AngeloRTV_Set_Callback(0, null);

            if (Mythread != IntPtr.Zero)
            {
                ISR_ON = 0;
                SetEvent(Event_Angelo[0]);
                Thread.Sleep(10);
                TerminateThread(Mythread, 0);
                Mythread = IntPtr.Zero;
            }

            Int_Count = 0;

            bmpinfo.bmiHeader.biSize = 40;
            bmpinfo.bmiHeader.biWidth = Cur_Width;
            bmpinfo.bmiHeader.biHeight = -Cur_Height;
            bmpinfo.bmiHeader.biPlanes = 1;
            bmpinfo.bmiHeader.biBitCount = 24;
            bmpinfo.bmiHeader.biCompression = 0;// BI_RGB
            bmpinfo.bmiHeader.biSizeImage = 0;
            bmpinfo.bmiHeader.biClrUsed = 0;
            bmpinfo.bmiHeader.biClrImportant = 0;

            ghdc = CreateCompatibleDC(GetDC(panel1.Handle));
            hbitbap = CreateDIBSection(ghdc, ref bmpinfo,0, out Temp0, IntPtr.Zero, 0);

            SelectObject(ghdc, hbitbap);

            AngeloRTV_Set_Color_Format(0, (byte)Byte_Pixel);
            AngeloRTV_Set_Video_Format(0, (byte)Cur_Video_Format);
            AngeloRTV_Set_Image_Config(0, 5, 0);
            AngeloRTV_Select_Channel(0, 1);
            //AngeloRTV_Set_Int_Event(0, Event_Angelo[0]);
            AngeloRTV_Capture_Start(0, long.MaxValue);

            AngeloRTV_Set_Callback(0, MyCallback);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            int result;

            iwidth = 384;
            iheight = 288;

            bmpinfo.bmiHeader.biBitCount = 24;
            bmpinfo.bmiHeader.biCompression = 0;// BI_RGB
            bmpinfo.bmiHeader.biPlanes = 1;
            bmpinfo.bmiHeader.biSize = 40;
            bmpinfo.bmiHeader.biWidth = iwidth;
            bmpinfo.bmiHeader.biHeight = -iheight;

            byte[] bBytes = new byte[iwidth * iheight * 3];

            IntPtr iDC = CreateCompatibleDC(panel1.Handle);
            IntPtr ppvBits;
            IntPtr iBitmap = CreateDIBSection(iDC, ref bmpinfo, 0, out ppvBits, IntPtr.Zero, 0);
            SelectObject(iDC, iBitmap);
            BitBlt(iDC, 0, 0, iwidth, iheight, this.Handle, 0, 0, (uint)TernaryRasterOperations.SRCCOPY);

            GetDIBits(iDC, iBitmap, 0, (uint)bmpinfo.bmiHeader.biHeight, bBytes, ref bmpinfo, (uint)DIB_RGB_COLORS);

            result = AngeloRTV_Set_Color_Format(0, 3);
            result = AngeloRTV_Set_Video_Format(0, 3);
            result = AngeloRTV_Set_Image_Config(0, 5, 0);

            bool start_capture = true;
            //while (start_capture)
            //{
            //    AngeloRTV_Sync_Grab(0, 
            //}


        }
    }
}
